package vcsn.handlers;

//import java.util.Set;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.ILocalVariable;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.*;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

import vcsn.entities.Class;
//import org.eclipse.jface.text.Document;
/**
 * Our sample handler extends AbstractHandler, an IHandler base class.
 * @see org.eclipse.core.commands.IHandler
 * @see org.eclipse.core.commands.AbstractHandler
 */
public class SampleHandler extends AbstractHandler {
	ASTParser parser = ASTParser.newParser(AST.JLS4);
	/**
	 * The constructor.
	 */
	public SampleHandler() {
	}

	/**
	 * the command has been executed, so extract extract the needed information
	 * from the application context.
	 */
	/*public Object execute(ExecutionEvent event) throws ExecutionException {
		IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
		MessageDialog.openInformation(
				window.getShell(),
				"Test",
				"Hello, Eclipse world");
		return null;
	}*/

	public Object execute(ExecutionEvent event) throws ExecutionException {
	    // Get the root of the workspace
	    //IWorkspace workspace = ResourcesPlugin.getWorkspace();
	    //IWorkspaceRoot root = workspace.getRoot();
	    // Get all projects in the workspace
	    //IProject[] projects = root.getProjects();
	    // Loop over all projects
	    IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
	    if (window != null)
	    {
	        IStructuredSelection selection = (IStructuredSelection) window.getSelectionService().getSelection();
	        Object firstElement = selection.getFirstElement();
	        if (firstElement instanceof IAdaptable)
	        {
	            IProject project = (IProject)((IAdaptable)firstElement).getAdapter(IProject.class);
	        }
	    }
	    //for (IProject project : projects) {
	      
	    //}
	    return null;
	  }
	
	private IJavaProject getIJavaProjectByIProject(IProject p) {
		return JavaCore.create(p);
	}

	  private void printProjectInfo(IProject project) throws CoreException, JavaModelException {
	    System.out.println("Working in project " + project.getName());
	    // check if we have a Java project
	    if (project.isNatureEnabled("org.eclipse.jdt.core.javanature")) {
	    	parser.setResolveBindings(true);
	    	printPackageInfos(getIJavaProjectByIProject(project));
	    }
	  }

	  private void printPackageInfos(IJavaProject javaProject)
	      throws JavaModelException {
	    IPackageFragment[] packages = javaProject.getPackageFragments();
	    for (IPackageFragment mypackage : packages) {
	      // Package fragments include all packages in the
	      // classpath
	      // We will only look at the package from the source
	      // folder
	      // K_BINARY would include also included JARS, e.g.
	      // rt.jar
	      if (mypackage.getKind() == IPackageFragmentRoot.K_SOURCE) {
	        System.out.println("Package " + mypackage.getElementName());
	        printICompilationUnitInfo(mypackage);

	      }

	    }
	  }

	  private void printICompilationUnitInfo(IPackageFragment mypackage)
	      throws JavaModelException {
	    for (ICompilationUnit unit : mypackage.getCompilationUnits()) {
	      printCompilationUnitDetails(unit);

	    }
	  }
	  
	  private void printCompilationUnitDetails(ICompilationUnit unit)
		    throws JavaModelException {
		    System.out.println("Source file " + unit.getPath().toString());
		    printIMethods(unit);
		  }

	  private void printIMethods(ICompilationUnit unit) throws JavaModelException {
	    IType[] allTypes = unit.getAllTypes();
	    for (IType type : allTypes) {
	    	String interfaceName = "CompilationUnit implement: ";
		    String interfaceType = "CompilationUnit implementedType: ";
		    if(type.getSuperclassName() != null){
	    	System.out.println("CompilationUnit parent:" + type.getSuperclassName());
	    	System.out.println("CompilationUnit parentType:" + type.getSuperclassTypeSignature());
		    }
	    	if(type.getSuperInterfaceNames().length > 0){
	    		for(int i = 0; i < type.getSuperInterfaceNames().length; i++){
	    			
	    			interfaceName += type.getSuperInterfaceNames()[i] + " ";
	    			interfaceType += type.getSuperInterfaceTypeSignatures()[i] + " ";
	    		}
	    		System.out.println(interfaceName);
		    	System.out.println(interfaceType);
	    	}
	    	System.out.println("CompilationUnit name:" + type.getFullyQualifiedName('.'));
	    	printIFieldDetails(type);
	    	printIMethodDetails(type);
	    }
	  }
  

	  private void printIMethodDetails(IType type) throws JavaModelException {
	    IMethod[] methods = type.getMethods();
	    for (IMethod method : methods) {
	      System.out.println("Method name " + method.getDeclaringType().getFullyQualifiedName('.') + "." + method.getElementName());
	      System.out.println("Signature " + method.getSignature());
	      System.out.println(method.isResolved());
	      ILocalVariable[] parameters =  method.getParameters();
	      for(ILocalVariable para : parameters){
	    	  System.out.println("Parameters name: " + para.getElementName());
	    	  System.out.println("Parameters type: " + para.getTypeSignature());
	      }
	      System.out.println("Return Type " + method.getReturnType());

	    }
	  }
	  
	  private void printIFieldDetails(IType type) throws JavaModelException{
		  IField[] variables = type.getFields();
		    for(IField field: variables){
		    	System.out.println(field.isResolved());
		    	System.out.println("Variable name: " + field.getDeclaringType().getFullyQualifiedName('.') +"." + field.getElementName());
		    	System.out.println("Variable type: " + field.getTypeSignature());
		    }
	  }
}
